// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

console.log("- SinbadEV's Cast Manager Running -");
if (!localStorage["settings_string"]) {localStorage["settings_string"] = "";};
if (!localStorage["hide_user"]) {localStorage["hide_user"] = 0;};
if (!localStorage["show_label"]) {localStorage["show_label"] = 0;};
if (!localStorage["mod_images"]) {localStorage["mod_images"] = 0;};
if (!localStorage["hide_joindate"]) {localStorage["hide_joindate"] = 0;};
if (!localStorage["hide_memberno"]) {localStorage["hide_memberno"] = 0;};
if (!localStorage["hide_location"]) {localStorage["hide_location"] = 0;};
if (!localStorage["hide_poststats"]) {localStorage["hide_poststats"] = 0;};
if (!localStorage["show_detail"]) {localStorage["show_detail"] = 2;};
if (!localStorage["show_sheetlink"]) {localStorage["show_sheetlink"] = 0;};
if (!localStorage["custom_avatar_height"]) {localStorage["custom_avatar_height"] = 60;};
if (!localStorage["custom_avatar_width"]) {localStorage["custom_avatar_width"] = 60;};
if (!localStorage["hide_status_br"]) {localStorage["hide_status_br"] = 0;};
if (!localStorage["on_update"]) {localStorage["on_update"] = 0;};
if (!localStorage["alter_postcount_links"]) {localStorage["alter_postcount_links"] = 0;};
if (!localStorage["cribsheet"]) {localStorage["cribsheet"] = 0;};


// Called when the url of a tab changes.
function checkForValidUrl(tabId, changeInfo, tab) {
  // If the letter 'g' is found in the tab's URL...
  if (tab.url.indexOf('forums') > -1) {
    // ... show the page action.
    chrome.pageAction.show(tabId);
	} else {
		chrome.contextMenus.removeAll()
	}
};

function getSettingsStringFromObject(settings_object) {
	var returnString = "";
	for (var game in settings_object.games) {
		returnString += "GAME="+game.toString()+";";
		//console.log(game);
		//console.log(settings_object.games[game].threads);
		//console.log(settings_object.games[game].players);
		for (var thread in settings_object.games[game].threads) {
			returnString += "THREAD="+thread.toString()+";";
		}
		for (var player in settings_object.games[game].players) {
			// settings string format for player nodes: PLAYER=userid|character_tag|character_image_url|character_detail|sheet_thread;
			returnString += "PLAYER="+player.toString()+"|";//userid
			if (settings_object.games[game].players[player].character_tag) {
				returnString += settings_object.games[game].players[player].character_tag;
			}
			returnString += "|";
			if (settings_object.games[game].players[player].character_image_url) {
				returnString += settings_object.games[game].players[player].character_image_url;
			}
			returnString += "|";
			if (settings_object.games[game].players[player].character_detail) {
				returnString += settings_object.games[game].players[player].character_detail;
			}
			returnString += "|";
			if (settings_object.games[game].players[player].sheet_thread) {
				returnString += settings_object.games[game].players[player].sheet_thread;
			}
			returnString += "|";
			if (settings_object.games[game].players[player].crib_sheet) {
				returnString += settings_object.games[game].players[player].crib_sheet;
			}
			returnString += ";";
		}
	}
	console.log('returning with');
	console.log(returnString);
	return returnString;
}

function removePlayerFromGame(gameTag, userid) {
	var settings_object = readSettingsObject ();
	delete settings_object.games[gameTag].players[userid];
	localStorage["settings_string"] = getSettingsStringFromObject(settings_object);
	dirtyPage("player "+userid+" removed from game "+gameTag);
}

function dirtyPage(message) {
	chrome.tabs.getSelected(null, function (tab) {
		chrome.tabs.sendRequest(tab.id, {method: "make_page_dirty", message: message, settings_object: new readSettingsObject()}, function(response) {
			console.log(response.answer);
		});
	});
}

function readSettingsObject ()
{
	var settings_object = settingsStringToObject(localStorage['settings_string']);
	settings_object.cached_settings_string = localStorage['settings_string'].toString();
	
	settings_object.hide_user = localStorage['hide_user'];
	settings_object.show_label = localStorage['show_label'];
	settings_object.mod_images = localStorage['mod_images'];
	
	
	settings_object.hide_joindate = localStorage['hide_joindate'];
	settings_object.hide_memberno = localStorage['hide_memberno'];
	settings_object.hide_location = localStorage['hide_location'];
	settings_object.hide_poststats = localStorage['hide_poststats'];
	
	settings_object.show_detail = localStorage["show_detail"]
	settings_object.show_sheetlink = localStorage["show_sheetlink"]
	
	settings_object.custom_avatar_height = localStorage["custom_avatar_height"]
	settings_object.custom_avatar_width = localStorage["custom_avatar_width"]
	
	settings_object.hide_status_br = localStorage["hide_status_br"]
	settings_object.on_update = localStorage["on_update"]

	settings_object.alter_postcount_links = localStorage["alter_postcount_links"]
	
	settings_object.cribsheet = localStorage["cribsheet"];
	
	return settings_object;
	
}

function writeSettingsObject (settings_object)
{
	console.log('writing settings object');
	localStorage['settings_string'] = getSettingsStringFromObject(settings_object);
	return true;
}

function settingsStringToObject(settings_string) {
//convert a settings_string to a settings object
var settings_object = new Object();
settings_object.games = new Object();
//console.log(settings_object);
if ((settings_string) && (settings_string.length > 0)) {
	var myList = settings_string.toString().split(';');
	var pair;
	var current_game = "";
	for (i=0; i<myList.length-1; i++)
		{	
			pair = myList[i].split('=');
			// Because the settings string uses = : and ; characters for specific purposes those characters should not be used in nodes without escaping them or something... otherwise I think any character that's valid in html body should be accepted.
			// settings string format for game nodes: GAME=Game Tag;
			if (pair[0] == "GAME") {
				var game = new Object();
				game.threads = new Object;
				game.players = new Object;
				current_game = pair[1];
				settings_object.games[pair[1]] = game;
			}
			// settings string format for thread nodes: THREAD=threadid;
			if (pair[0] == "THREAD") {
				settings_object.games[current_game].threads[pair[1]] = new Object();
				// the "game.threads array will contain objects with indexes of threadid... because I'm crazy and may want to add thread specific stuff in the future.
			}
			// settings string format for player nodes: PLAYER=userid:character_tag:character_image_url:character_detail;
			if (pair[0] == "PLAYER") {
				var player = new Object();
				var player_info = pair[1].split('|');
				if (player_info.length > 1) {
					player.character_tag = player_info[1]; // game specific Character Name to display
				} else {
					player.character_tag = "";
				};
				if (player_info.length > 2) {
					player.character_image_url = player_info[2]; // game specific URL of Avatar to display
				} else {
					player.character_image_url = "";
				};
				if (player_info.length > 3) {
					player.character_detail = player_info[3]; // game specific title (like "Halfling Rogue") 
				} else {
					player.character_detail = "";
				};
				if (player_info.length > 4) {
					player.sheet_thread = player_info[4];
				} else {
					player.sheet_thread = "";
				};
				if (player_info.length > 5) {
					player.crib_sheet = player_info[5];
				} else {
					player.crib_sheet = "";
				};
				
				
				settings_object.games[current_game].players[player_info[0]] = player;
			}
		
		}
		//console.log("Settings Object:");
		//console.log(settings_object);
} else {
	console.log("settings_string is empty");
}

return settings_object;
}



function promptForNewGame(thread) {
	var tag=prompt("Please enter the tag for your new game:");
	if (tag) {
		addNewGame(tag, thread);
	}
}

function addThreadToGame(game, thread) {
	var settings_object = new readSettingsObject ()
	settings_object.games[game].threads[thread] = new Object();
	if (writeSettingsObject(settings_object)){
		dirtyPage("thread "+thread+" added to game "+game);
	} else {
		dirtyPage("write returned false");
	}
}

function addPlayerToGame(gameTag, userid) {
	//also used for renaming
	var settings_object = new readSettingsObject();
	var old_character_tag = "";
	if (settings_object.games[gameTag].players[userid] && settings_object.games[gameTag].players[userid].character_tag) {
		old_character_tag = settings_object.games[gameTag].players[userid].character_tag;
	}
	var character_tag=prompt("Please enter the GameNick for "+userid+" in "+gameTag+" (leave blank for none):",old_character_tag);
	if (!(character_tag == null)) {
		// settings string format for player nodes: PLAYER=userid|character_tag|character_image_url|character_detail|sheet_thread;
		if (!settings_object.games[gameTag].players[userid]) {
			settings_object.games[gameTag].players[userid] = new Object();
		}
		settings_object.games[gameTag].players[userid].character_tag = character_tag;
		//console.log("Updated Settings Object:")
		//console.log(settings_object);
		var result = getSettingsStringFromObject(settings_object);
		//console.log("Updated Settings String:")
		//console.log(result);
		localStorage["settings_string"] = result;
		dirtyPage("player "+userid+" added to (or renamed in) game "+gameTag);
		return true;
	} else {
		console.log("player not added, user cancelled.");
		return false;
	}

}

function setPlayerAvatar(gameTag, userid) {

	var settings_object = new readSettingsObject();
	var old_character_image_url = "";
	if (settings_object.games[gameTag].players[userid].character_image_url) {
		old_character_image_url = settings_object.games[gameTag].players[userid].character_image_url;
	}
	var character_image_url=prompt("Please enter the url for "+userid+" in "+gameTag+" (leave blank for default):",old_character_image_url);
	if (!(character_image_url == null)) {
		// settings string format for player nodes: PLAYER=userid|character_tag|character_image_url|character_detail|sheet_thread;
		if (!settings_object.games[gameTag].players[userid]) {
			settings_object.games[gameTag].players[userid] = new Object();
		}
		settings_object.games[gameTag].players[userid].character_image_url = character_image_url;
		//console.log("Updated Settings Object:")
		//console.log(settings_object);
		var result = getSettingsStringFromObject(settings_object);
		//console.log("Updated Settings String:")
		//console.log(result);
		localStorage["settings_string"] = result;
		dirtyPage("set player "+userid+"'s Avatar for game "+gameTag+" to <img src='"+character_image_url+"' width='16px' height='16px' />");
	} else {
		console.log("player not updated, user didn't provide a valid character_image_url.");
	}

}

function setPlayerSheetThread(player_string, gameTag, userid, thread) {
	//also used for renaming
	var settings_object = new readSettingsObject();
	if (settings_object.games[gameTag].players[userid].sheet_thread) {
		thread = settings_object.games[gameTag].players[userid].sheet_thread;
	}
	var sheet_thread=prompt("Please enter the id of the thread for "+player_string+"'s ("+userid+") character sheet in "+gameTag+" (leave blank for none):",thread);
	if (!(sheet_thread == null)) {
		//get the settings_object
		
		// settings string format for player nodes: PLAYER=userid|character_tag|character_image_url|character_detail|sheet_thread;
		if (!settings_object.games[gameTag].players[userid]) {
			settings_object.games[gameTag].players[userid] = new Object();//add the player if not already in this game
		}
		settings_object.games[gameTag].players[userid].sheet_thread = sheet_thread;
		writeSettingsObject(settings_object);
		dirtyPage("set player "+userid+"'s character sheet for game "+gameTag+" to <a href='showthread.php?t=12338"+sheet_thread+"'>"+sheet_thread+"</a>");
	} else {
		console.log("player not updated, user cancelled.");
	}
}

function setPlayerDetail(player_string, gameTag, userid) {
	//also used for renaming
	var settings_object = new readSettingsObject();
	var old_character_detail = "";
	if (settings_object.games[gameTag].players[userid].character_detail) {
		old_character_detail = settings_object.games[gameTag].players[userid].character_detail;
	}
	var character_detail=prompt("Please enter the detail (custom title) for "+player_string+"'s ("+userid+") character sheet in "+gameTag+" (leave blank for none):", old_character_detail);
	if (!(character_detail == null)) {
		//get the settings_object
		
		// settings string format for player nodes: PLAYER=userid|character_tag|character_image_url|character_detail|sheet_thread;
		if (!settings_object.games[gameTag].players[userid]) {
			settings_object.games[gameTag].players[userid] = new Object();//add the player if not already in this game
		}
		settings_object.games[gameTag].players[userid].character_detail = character_detail;
		writeSettingsObject(settings_object);
		dirtyPage("set player "+userid+"'s character detail for game "+gameTag+" to '"+character_detail+"'.");
	} else {
		console.log("player not updated, user cancelled.");
	}
}

function addNewGame(tag, thread) {
	var tempSettings = localStorage['settings_string'];
	if (!tempSettings) {tempSettings="";}
	if ((tempSettings.indexOf("GAME="+tag) > -1) || (tempSettings.indexOf("THREAD="+thread) > -1)) {
		//oops, thread or game already exists,
		alert('thread already in a game or game already exists. Please manually correct problem in options page.');
	} else {
		
		localStorage['settings_string'] = tempSettings + "GAME="+tag+";THREAD="+thread+";";
		dirtyPage("Created new game "+tag);
	}

	/*
	console.log('addNewGame has executed with parameters:');
	console.log("tag="+tag);
	console.log("thread="+thread);
	console.log('resulting in:');
	console.log("tempSettings="+tempSettings);
	console.log("localStorage['settings_string']="+localStorage['settings_string']);
	//*/
	
}

function addToGame(tag, thread) {
	var tempSettings = localStorage['settings_string'];
	if (!tempSettings) {tempSettings="";}

	//console.log(tempSettings);
	if (tempSettings.indexOf("THREAD="+thread) > -1) {
		//oops, thread or game already exists,
		alert('error and/or thread already in a game. Please manually correct problem in options page.');
	} else {
		var tempSettings = localStorage['settings_string'];
		var newSettings = "";
		var myList = tempSettings.toString().split(';');
		for (i=0; i<myList.length-1; i++)
			{	
				newSettings += myList[i]+";";
				//console.log(myList[i]);
				//console.log("GAME="+tag);
				if (myList[i] == "GAME="+tag) {
					//console.log("!!!!!!!!!!!!");
					dirtyPage("Thread "+thread+" added to game "+tag);
					newSettings += "THREAD="+thread+";";
				}
			
			}
	}
		//console.log(newSettings);
		localStorage['settings_string'] = newSettings;


}

// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);
chrome.tabs.onSelectionChanged.addListener(function () {chrome.contextMenus.removeAll()});
chrome.extension.onRequest.addListener(function(request) {
	var settings_object = readSettingsObject ();
	
	if  ((request.cmd == "createAvatarMenu") && (request.gameTag)) {
		
		chrome.contextMenus.removeAll(function() {
			chrome.contextMenus.create({
				"title": "Set custom image for "+request.avatar_label+" ("+request.userid+") in "+request.gameTag,
				"contexts":["image"],
				"onclick": function (){setPlayerAvatar(request.gameTag, request.userid)}
			});
		});
	}
    if (request.cmd == "createRegularMenu") {
		//console.log("regular");
		if (!request.gameTag) {
        chrome.contextMenus.removeAll(function() {
			chrome.contextMenus.create({
				"title": "Create Game for thread: "+request.thread,
				"contexts":["page"],
				"onclick": function (){promptForNewGame(request.thread)}
			});
			
			for (game in settings_object.games)
			{	
				chrome.contextMenus.create({
					"title": "Add thread("+request.thread+") to game: "+game,
					"contexts":["page"],
					"onclick": (function(element) {
							return function(info, tab) {
								addThreadToGame(element,request.thread)
							}
						})(game)
				
				});
			}
        });
		
		/*
		http://stackoverflow.com/questions/5567437/selection-and-site-search-in-chrome-extension
			chrome.contextMenus.create({
    "title": "find ' %s' ? "+ ar[i],
    "contexts": [ "selection"],
    "onclick" : (function(element) {
                    return function(info, tab) {
                        var baseUrl = "http://www.google.com/search?q=site%3A";

                        if (info.selectionText) {
                            baseUrl += element + "&q="+ encodeURI(info.selectionText);
                            chrome.tabs.create({"url": baseUrl});
                        }
                    }
                })(ar[i])
});
		*/
		} else {
			chrome.contextMenus.removeAll(function() {
				chrome.contextMenus.create({
					"title": "Remove thread from: "+request.gameTag,
					"contexts":["page"],
					"onclick": function (){removeThreadFromGame(request.thread, request.gameTag);}
				});
			});
		}
    } else if (request.cmd == "createUserMenu") {
		//console.log("user");
		//user in game?

        chrome.contextMenus.removeAll(function() {
			var user_in_game = "Error?";
			if (!settings_object.games[request.gameTag]) {
				
			} else if (!settings_object.games[request.gameTag].players || !settings_object.games[request.gameTag].players[request.userid]) {
				chrome.contextMenus.create({
					"title": "Add user "+request.user_name+" ("+request.userid+") to "+request.gameTag,
					"contexts":["link"],
					"onclick": function () {addPlayerToGame(request.gameTag, request.userid)}
				});
			} else {
				chrome.contextMenus.create({
					"title": "Remove user "+request.user_name+" ("+request.userid+") from "+request.gameTag,
					"contexts":["link"],
					"onclick": function () {removePlayerFromGame(request.gameTag, request.userid)}
				});
				chrome.contextMenus.create({
					"title": "Rename user "+request.user_name+" ("+request.userid+") in "+request.gameTag,
					"contexts":["link"],
					"onclick": function () {addPlayerToGame(request.gameTag, request.userid)}
				});
				chrome.contextMenus.create({
					"title": "Set character sheet for "+request.user_name+" ("+request.userid+") in "+request.gameTag,
					"contexts":["link"],
					"onclick": function () {setPlayerSheetThread(request.user_name, request.gameTag, request.userid, request.thread)}
				});
				chrome.contextMenus.create({
					"title": "Set player detail for user "+request.user_name+" ("+request.userid+") in "+request.gameTag,
					"contexts":["link"],
					"onclick": function () {setPlayerDetail(request.user_name, request.gameTag, request.userid)}
				});

			}

        });
		
    } else if (request.cmd == "zeroMenu") {
		//console.log("zero");
        chrome.contextMenus.removeAll(function() {
			//Nothing
        });
    }
});

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
	if (request.method == "add_player") {
		console.log(request);
		sendResponse({result: addPlayerToGame(request.game, request.player)});
    } else if (request.method == "read_settings") {
		console.log('request received for "read_settings" with request:')
		console.log(request);
		var settings_object = new readSettingsObject();
		sendResponse({settings_object: settings_object});
    } else if (request.method == "get_settings_string") {
		console.log('request received for "get_settings_string" with request:')
		console.log(request);
	  var returningobject = new Object();
	  returningobject.settings_string = localStorage['settings_string'];
	  returningobject.hide_user = localStorage['hide_user'];
	  returningobject.show_label = localStorage['show_label'];
	  returningobject.mod_images = localStorage['mod_images'];
      //sendResponse({settings_string: localStorage['settings_string']});
	  returningobject.settings_object = settingsStringToObject(returningobject.settings_string);
	  sendResponse({returningobject: returningobject});
    } else if (request.method == "write_settings_object") {
		if (request.settings_object) {
			console.log('request received for "write_settings_object" with request:')
			console.log(request);
			console.log(request.settings_object);
			sendResponse({returningobject: writeSettingsObject(request.settings_object)});
		}
	} else {
      sendResponse({}); // snub them.
	}
	
	
});

function removeThreadFromGame(thread, gameTag) {
	var new_settings_object = new readSettingsObject();
	var confirm_value=confirm("Click OK to remove "+thread+" from "+gameTag+". Click CANCEL if you do not wish to remove.");
	if (confirm_value) {delete new_settings_object.games[gameTag].threads[thread]};
	if (writeSettingsObject(new_settings_object)) {
		dirtyPage("thread "+thread+" removed from game "+gameTag);
	} else {

	};
}